{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#coding=gbk\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from modelBATTERY\\model.ckpt-1000\n",
      "Load!\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "#定义常量\n",
    "rnn_unit=15       #hidden layer units\n",
    "input_size=11\n",
    "output_size=1\n",
    "PATH = \"modelBATTERY\"\n",
    "lr=0.0006         #学习率\n",
    "#——————————————————导入数据——————————————————————\n",
    "f=open('dataset/B0005_1.csv')\n",
    "df=pd.read_csv(f)     #读入数据\n",
    "data=df.iloc[:,3:15].values  #取第4-14列\n",
    "\n",
    "\n",
    "#获取训练集\n",
    "def get_train_data(batch_size=60,time_step=20,train_begin=1,train_end=300):\n",
    "    batch_index=[]\n",
    "    data_train=data[train_begin:train_end]\n",
    "    normalized_train_data=(data_train-np.mean(data_train,axis=0))/np.std(data_train,axis=0)  #标准化\n",
    "    train_x,train_y=[],[]   #训练集 \n",
    "    for i in range(len(normalized_train_data)-time_step):\n",
    "       if i % batch_size==0:\n",
    "           batch_index.append(i)\n",
    "       x=normalized_train_data[i:i+time_step,:11]\n",
    "       y=normalized_train_data[i:i+time_step,11,np.newaxis]\n",
    "       train_x.append(x.tolist())\n",
    "       train_y.append(y.tolist())\n",
    "    batch_index.append((len(normalized_train_data)-time_step))\n",
    "    return batch_index,train_x,train_y\n",
    "\n",
    "\n",
    "\n",
    "#获取测试集\n",
    "def get_test_data(time_step=20,test_begin=1):\n",
    "    data_test=data[test_begin:]\n",
    "    mean=np.mean(data_test,axis=0)\n",
    "    std=np.std(data_test,axis=0)\n",
    "    normalized_test_data=(data_test-mean)/std  #标准化\n",
    "    size=(len(normalized_test_data)+time_step-1)//time_step  #有size个sample \n",
    "    test_x,test_y=[],[]  \n",
    "    for i in range(size-1):\n",
    "       x=normalized_test_data[i*time_step:(i+1)*time_step,:11]\n",
    "       y=normalized_test_data[i*time_step:(i+1)*time_step,11]\n",
    "       test_x.append(x.tolist())\n",
    "       test_y.extend(y)\n",
    "    test_x.append((normalized_test_data[(i+1)*time_step:,:11]).tolist())\n",
    "    test_y.extend((normalized_test_data[(i+1)*time_step:,11]).tolist())\n",
    "    return mean,std,test_x,test_y\n",
    "\n",
    "\n",
    "\n",
    "#——————————————————定义神经网络变量——————————————————\n",
    "#输入层、输出层权重、偏置\n",
    "\n",
    "weights={\n",
    "         'in':tf.Variable(tf.random_normal([input_size,rnn_unit])),\n",
    "         'out':tf.Variable(tf.random_normal([rnn_unit,1]))\n",
    "        }\n",
    "biases={\n",
    "        'in':tf.Variable(tf.constant(0.1,shape=[rnn_unit,])),\n",
    "        'out':tf.Variable(tf.constant(0.1,shape=[1,]))\n",
    "       }\n",
    "\n",
    "#——————————————————定义神经网络变量——————————————————\n",
    "def lstm(X):     \n",
    "    batch_size=tf.shape(X)[0]\n",
    "    time_step=tf.shape(X)[1]\n",
    "    w_in=weights['in']\n",
    "    b_in=biases['in']  \n",
    "    input=tf.reshape(X,[-1,input_size])  #需要将tensor转成2维进行计算，计算后的结果作为隐藏层的输入\n",
    "    input_rnn=tf.matmul(input,w_in)+b_in\n",
    "    input_rnn=tf.reshape(input_rnn,[-1,time_step,rnn_unit])  #将tensor转成3维，作为lstm cell的输入\n",
    "    cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit)\n",
    "    init_state=cell.zero_state(batch_size,dtype=tf.float32)\n",
    "    output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)  #output_rnn是记录lstm每个输出节点的结果，final_states是最后一个cell的结果\n",
    "    output=tf.reshape(output_rnn,[-1,rnn_unit]) #作为输出层的输入\n",
    "    w_out=weights['out']\n",
    "    b_out=biases['out']\n",
    "    pred=tf.matmul(output,w_out)+b_out\n",
    "    return pred,final_states\n",
    "\n",
    "\n",
    "\n",
    "#——————————————————训练模型——————————————————\n",
    "def train_lstm(batch_size=80,time_step=15,train_begin=1,train_end=300):\n",
    "    X=tf.placeholder(tf.float32, shape=[None,time_step,input_size])\n",
    "    Y=tf.placeholder(tf.float32, shape=[None,time_step,output_size])\n",
    "    batch_index,train_x,train_y=get_train_data(batch_size,time_step,train_begin,train_end)\n",
    "    pred,_=lstm(X)\n",
    "    #损失函数\n",
    "    loss=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))\n",
    "    train_op=tf.train.AdamOptimizer(lr).minimize(loss)\n",
    "    saver=tf.train.Saver(tf.global_variables(),max_to_keep=15)\n",
    "    # module_file = tf.train.latest_checkpoint()\n",
    "    with tf.Session() as sess:\n",
    "        sess.run(tf.global_variables_initializer())\n",
    "        ckpt = tf.train.get_checkpoint_state(PATH)\n",
    "        if ckpt and ckpt.model_checkpoint_path:\n",
    "            saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "            print(\"Load!\")\n",
    "        else:\n",
    "            tf.global_variables_initializer().run()\n",
    "        # saver.restore(sess, module_file)\n",
    "        #重复训练10000次\n",
    "        for i in range(1001):\n",
    "            for step in range(len(batch_index)-1):\n",
    "                _,loss_=sess.run([train_op,loss],feed_dict={X:train_x[batch_index[step]:batch_index[step+1]],Y:train_y[batch_index[step]:batch_index[step+1]]})\n",
    "            print(i,loss_)\n",
    "            if i % 200==0:\n",
    "                saver.save(sess, 'modelBATTERY/model.ckpt', global_step=i)\n",
    "                print(\"保存模型：\")\n",
    "\n",
    "\n",
    "\n",
    "#————————————————预测模型————————————————————\n",
    "def prediction(time_step=20):\n",
    "    X=tf.placeholder(tf.float32, shape=[None,time_step,input_size])\n",
    "    #Y=tf.placeholder(tf.float32, shape=[None,time_step,output_size])\n",
    "    mean,std,test_x,test_y=get_test_data(time_step)\n",
    "    pred,_=lstm(X)     \n",
    "    saver=tf.train.Saver(tf.global_variables())\n",
    "    with tf.Session() as sess:\n",
    "        #参数恢复\n",
    "        ckpt = tf.train.get_checkpoint_state(PATH)\n",
    "        if ckpt and ckpt.model_checkpoint_path:\n",
    "            saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "            print(\"Load!\")\n",
    "        else:\n",
    "            tf.global_variables_initializer().run()\n",
    "        # module_file = tf.train.latest_checkpoint()\n",
    "        # saver.restore(sess, module_file)\n",
    "        test_predict=[]\n",
    "        for step in range(len(test_x)-1):\n",
    "            prob=sess.run(pred,feed_dict={X:[test_x[step]]})   \n",
    "            predict=prob.reshape((-1))\n",
    "            test_predict.extend(predict)\n",
    "        test_y=np.array(test_y)*std[11]+mean[11]\n",
    "        test_y1 = test_y[:300]\n",
    "        test_y2 = test_y[301:]\n",
    "        test_predict=np.array(test_predict)*std[11]+mean[11]\n",
    "        acc=np.average(np.abs(test_predict-test_y[:len(test_predict)])/test_y[:len(test_predict)])  #偏差\n",
    "        #以折线图表示结果\n",
    "        plt.figure()\n",
    "        plt.plot(list(range(len(test_predict))), test_predict, color='b')\n",
    "        plt.plot(list(range(len(test_y1))), test_y1,  color='r')\n",
    "        plt.plot(list(range(len(test_y))), test_y2,  color='g')\n",
    "        plt.show()\n",
    "        \n",
    "\n",
    "\n",
    "# train_lstm()\n",
    "\n",
    "prediction() "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
